/*
 * Copyright Notice ====================================================
 * This file contains proprietary information of JeeStrap Co.
 * Copying or reproduction without prior written approval is prohibited.
 * Copyright (c) 2014 All rights reserved. =============================
 */

package com.jeestrap.common.smartcoder.gui.setting;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.jeestrap.common.smartcoder.database.DbUtil;
import com.jeestrap.common.smartcoder.domain.CodeDesc;
import com.jeestrap.common.smartcoder.domain.DbTable;
import com.jeestrap.common.smartcoder.domain.DriverInfo;
import com.jeestrap.common.smartcoder.domain.OrmTableField;
import com.jeestrap.common.smartcoder.generator.CodeGeneratorEngine;
import com.jeestrap.common.smartcoder.gui.codeview.CodeViewFrame;
import com.jeestrap.common.smartcoder.util.StrUtils;

public class SettingFrame extends JFrame implements ActionListener {

	/**
	 * serialVersionUID long
	 */
	private static final long serialVersionUID = 1182685843281787021L;

	private JPanel naviPanel;

	private JTabbedPane m_tabbedPane;

	ProjectSettingPanel outPanel = new ProjectSettingPanel();

	OrmSettingPanel ormPanel = new OrmSettingPanel();

	private JPanel btnPanel;

	private JButton previewButton;

	CodeDesc codeDesc = new CodeDesc();

	/**
	 * Create the frame.
	 */
	public SettingFrame() {

		System.out.println("JeeWeb - 代码生成器   START");

		// 设置框架窗体的事件监听(关闭窗体事件)
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				DbUtil.realseConnection();
				System.exit(0);
			}
		});

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("JeeWeb - 代码生成器");
		setIconImage(new ImageIcon(ClassLoader.getSystemResource("logo.png")).getImage());

		createNaviPane();
		createTabbedPane();
		createBtnPane();

		getContentPane().add("North", naviPanel);
		getContentPane().add("Center", m_tabbedPane);
		getContentPane().add("South", btnPanel);

		loadDefaultConfig();

		Dimension localDimension = Toolkit.getDefaultToolkit().getScreenSize();
		// int width = (int)(localDimension.getWidth());
		// int height = (int)(localDimension.getHeight());
		int width = 900;
		int height = 600;
		// this.setSize((int)localDimension.getWidth(), (int)localDimension.getHeight());
		this.setBounds(0, 0, width, height);
		this.setSize(width, height);
		this.setLocation((int)(localDimension.getWidth() - this.getWidth()) / 2,
			(int)(localDimension.getHeight() - this.getHeight()) / 2);
	}

	/**
	 * 下面是导航面板的创建过程
	 * 
	 * @return
	 * 
	 * @since
	 */
	private JPanel createNaviPane() {
		naviPanel = new JPanel();
		JLabel settingNaviLabel = new JLabel("项目&数据库设置");
		settingNaviLabel.setHorizontalAlignment(SwingConstants.LEFT);
		// 把四个功能按钮加入功能按钮面板中
		naviPanel.add(settingNaviLabel, JPanel.LEFT_ALIGNMENT);
		return naviPanel;
	}

	/**
	 * 下面是设置面板的创建过程
	 * 
	 * @return
	 * 
	 * @since
	 */
	private JTabbedPane createTabbedPane() {
		m_tabbedPane = new JTabbedPane(SwingConstants.TOP);

		// 创建选项卡
		m_tabbedPane.addTab("基础配置", outPanel);
		m_tabbedPane.addTab("数据库及映射配置", ormPanel);
		// 设置显示第一个选项卡
		m_tabbedPane.setSelectedIndex(0);

		m_tabbedPane.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				if (1 == m_tabbedPane.getSelectedIndex()) {

					if (DbUtil.getDBConnection() == null) {
						DriverInfo localDriverInfo = (DriverInfo)outPanel.driverComboBox.getSelectedItem();
						String dbName = null;
						if (localDriverInfo != null) {
							dbName = localDriverInfo.getDbName();
						}
						String driver = outPanel.driverClassTextField.getText().trim();
						String url = outPanel.URLTextField.getText().trim();
						String user = outPanel.userTextField.getText().trim();
						String password = new String(outPanel.passwordTextField.getPassword());
						try {
							DbUtil.getDBConnection(dbName, driver, url, user, password);
						} catch (Throwable localThrowable) {
							localThrowable.printStackTrace();
						}

						ormPanel.tableNameComboBox.removeAllItems();
						ormPanel.functionIdTextField.setText("");
						ormPanel.functionNameTextField.setText("");
						List<DbTable> localList = DbUtil.getAllTables();
						ormPanel.tableNameComboBox.addItem(new DbTable());
						for (int i = 0; i < localList.size(); i++) {
							ormPanel.tableNameComboBox.addItem(localList.get(i));
							ormPanel.tableNameComboBox.setSelectedIndex(0);
						}
					}
				}
			}
		});

		return m_tabbedPane;
	}

	/**
	 * 下面是按钮面板的创建过程
	 * 
	 * @return
	 * 
	 * @since
	 */
	private JPanel createBtnPane() {
		btnPanel = new JPanel();
		previewButton = new JButton("预览代码");
		// 添加事件监听器
		previewButton.addActionListener(this);
		previewButton.setEnabled(false);
		btnPanel.add(previewButton);
		return btnPanel;
	}

	public void actionPerformed(ActionEvent e) {

		if (e.getSource() == previewButton) {
			if (chekBasicSetting() && chekDBSetting() && chekOrmSetting() && chekSaveCodeSetting() ) {

				saveConfig();

				Map<String, String> genCodeMap = null;
				CodeGeneratorEngine codeGeneratorEngine = new CodeGeneratorEngine(codeDesc);
				try {
					genCodeMap = codeGeneratorEngine.genCode();
				} catch (Exception e1) {
					System.out.println("代码生成出错 error: " + e1.getMessage());
					JOptionPane.showMessageDialog(this, "代码生成出错", "Error", 0);
					return;
				}

				// 显示预览code窗口
				// this.dispose();
				this.setVisible(false);
				CodeViewFrame frame = new CodeViewFrame(this, codeDesc, genCodeMap);
				frame.setVisible(true);
			}
		}
	}

	private List<OrmTableField> getAllChooseFields() {
		List<OrmTableField> localArrayList = new ArrayList<OrmTableField>();
		OrmTableField[] arrayOfTableField = (OrmTableField[])ormPanel.voFieldModel.toArray(new OrmTableField[0]);
		for (int i = 0; i < arrayOfTableField.length; i++)
			if (Boolean.TRUE.equals(arrayOfTableField[i].getChoosed()))
				localArrayList.add(arrayOfTableField[i]);
		return localArrayList;
	}

	private boolean chekBasicSetting() {
		// 项目基础配置
		String projName = StrUtils.trim(outPanel.projNameTextField.getText());
		String baseFolder = StrUtils.trim(outPanel.baseFolderTextField.getText());
		String srcFolder = StrUtils.trim(outPanel.srcFolderTextField.getText());
		String webFolder = StrUtils.trim(outPanel.webFolderTextField.getText());
		String basePackage = StrUtils.trim(outPanel.basePackageTextField.getText());
		String module = StrUtils.trim(outPanel.moduleTextField.getText());
		String subModule = StrUtils.trim(outPanel.subModuleTextField.getText());
		if (StrUtils.isNull(projName)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请填写项目名称", "Error", 0);
			return false;
		}
		if (StrUtils.isNull(baseFolder)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请选择或者填写项目目录", "Error", 0);
			return false;
		}
		if (StrUtils.isNull(srcFolder)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请填写Src目录", "Error", 0);
			return false;
		}
		if (StrUtils.isNull(webFolder)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请填写Web目录", "Error", 0);
			return false;
		}
		if (StrUtils.isNull(basePackage)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请填写基础包名", "Error", 0);
			return false;
		}
		if (StrUtils.isNull(module)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请填写模块名", "Error", 0);
			return false;
		}
		codeDesc.setProjType(outPanel.projType);
		System.out.println("outPanel.projType{}"+outPanel.projType);
		codeDesc.setProjectPath(baseFolder + "\\" + projName);
		codeDesc.setJavaPath(srcFolder);
		codeDesc.setWebPath(webFolder);
		codeDesc.setBasePackage(basePackage);
		codeDesc.setModuleName(module);
		codeDesc.setSubModuleName(subModule);
		codeDesc.setClassAuthor("JeeStrap");
		codeDesc.setInitProject(outPanel.initProjectCheckBox.isSelected());
		String packageName = codeDesc.getBasePackage() + ".modules." + codeDesc.getModuleName();
		codeDesc.setPackageName(packageName);
		return true;
	}

	private boolean chekDBSetting() {
		// DB 配置
		DriverInfo localDriverInfo = (DriverInfo)outPanel.driverComboBox.getSelectedItem();
		String dbName = null;
		if (localDriverInfo != null) {
			dbName = localDriverInfo.getDbName();
		}
		String driver = outPanel.driverClassTextField.getText().trim();
		String url = outPanel.URLTextField.getText().trim();
		String user = outPanel.userTextField.getText().trim();
		String password = new String(outPanel.passwordTextField.getPassword());
		if (StrUtils.isNull(dbName)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请选择连接类型", "Error", 0);
			return false;
		}
		if (StrUtils.isNull(driver)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请填写驱动类名", "Error", 0);
			return false;
		}
		if (StrUtils.isNull(url)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请填写连接URL", "Error", 0);
			return false;
		}
		if (StrUtils.isNull(user)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请填写连接用户", "Error", 0);
			return false;
		}
		if (StrUtils.isNull(password)) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请填写连接密码", "Error", 0);
			return false;
		}

		return true;
	}

	private boolean chekSaveCodeSetting() {
		List<String> genClassNameList = new LinkedList<String>();

		String clzFilePath = codeDesc.getProjectPath() + "\\" + codeDesc.getJavaPath() + "\\"
			+ codeDesc.getPackageName().replace(".", "\\");
		codeDesc.setJavaPath(clzFilePath);
		String viewFilePath = codeDesc.getProjectPath() + "\\" + codeDesc.getWebPath() + "\\modules\\"
			+ codeDesc.getModuleName();
		if (!StrUtils.isNull(codeDesc.getSubModuleName())) {
			viewFilePath = viewFilePath + "\\" + codeDesc.getSubModuleName();
		}
		codeDesc.setWebPath(viewFilePath);

		boolean bln = false;
		if (outPanel.entityCheckBox.isSelected()) {
			genClassNameList.add(clzFilePath + "\\entity\\"
				+ (StrUtils.isNull(codeDesc.getSubModuleName()) ? "" : codeDesc.getSubModuleName() + "\\")
				+ StrUtils.capitalize(codeDesc.getClassName()) + "Entity.java");
			bln = true;
		}
		if (outPanel.serviceCheckBox.isSelected()) {
			genClassNameList.add(clzFilePath + "\\service\\"
				+ (StrUtils.isNull(codeDesc.getSubModuleName()) ? "" : codeDesc.getSubModuleName() + "\\")
				+ StrUtils.capitalize(codeDesc.getClassName()) + "Service.java");
			bln = true;
		}
		if (outPanel.controllerCheckBox.isSelected()) {
			genClassNameList.add(clzFilePath + "\\controller\\"
				+ (StrUtils.isNull(codeDesc.getSubModuleName()) ? "" : codeDesc.getSubModuleName() + "\\")
				+ StrUtils.capitalize(codeDesc.getClassName()) + "Controller.java");
			bln = true;
		}
		if (outPanel.daoCheckBox.isSelected()) {
			genClassNameList.add(clzFilePath + "\\dao\\"
				+ (StrUtils.isNull(codeDesc.getSubModuleName()) ? "" : codeDesc.getSubModuleName() + "\\")
				+ StrUtils.capitalize(codeDesc.getClassName()) + "Dao.java");
			bln = true;
		}
		if (outPanel.queryJspCheckBox.isSelected()) {
			genClassNameList.add(viewFilePath + "\\" + StrUtils.uncapitalize(codeDesc.getClassName()) + "List.jsp");
			bln = true;
		}
		if (outPanel.editspCheckBox.isSelected()) {
			genClassNameList.add(viewFilePath + "\\" + StrUtils.uncapitalize(codeDesc.getClassName()) + "Form.jsp");
			bln = true;
		}
		// if (outPanel.sqlCheckBox.isSelected()) {
		// genClassNameList.add(outPanel.sqlCheckBox.getText());
		// bln = true;
		// }
		if (!bln) {
			this.m_tabbedPane.setSelectedIndex(0);
			JOptionPane.showMessageDialog(this, "请至少选择一个需要保存的代码类型", "Error", 0);
			return false;
		}
		codeDesc.setGenClassNameList(genClassNameList);
		return bln;
	}

	private boolean chekOrmSetting() {

		String className = StrUtils.trim(ormPanel.functionIdTextField.getText());
		if (StrUtils.isNull(className)) {
			this.m_tabbedPane.setSelectedIndex(1);
			JOptionPane.showMessageDialog(this, "请填写Java类名", "Error", 0);
			return false;
		}

		String functionName = StrUtils.trim(ormPanel.functionNameTextField.getText());
		if (StrUtils.isNull(functionName)) {
			this.m_tabbedPane.setSelectedIndex(1);
			JOptionPane.showMessageDialog(this, "请填写功能名称", "Error", 0);
			return false;
		}

		codeDesc.setClassName(className);
		codeDesc.setFunctionName(functionName);
		
		DbTable dbTable = (DbTable)ormPanel.tableNameComboBox.getSelectedItem();
		codeDesc.setTableName(dbTable.getTblName());
		codeDesc.setOrmTableFieldList(getAllChooseFields());

		return true;
	}

	private void loadDefaultConfig() {
		try {
			String str = "app-config.properties";
			InputStream localInputStream = ClassLoader.getSystemResourceAsStream(str);
			if (localInputStream == null)
				localInputStream = getClass().getResourceAsStream(str);

			if (localInputStream != null) {
				Properties localProperties = new Properties();
				localProperties.load(localInputStream);
				localInputStream.close();
				String str1 = localProperties.getProperty("driver");
				String str2 = localProperties.getProperty("driverClass");
				String str3 = localProperties.getProperty("driverURL");
				String str4 = localProperties.getProperty("driverUser");
				String str5 = localProperties.getProperty("driverPassword");
				String str6 = localProperties.getProperty("baseFolder");
				String projName = localProperties.getProperty("projName");
				String str7 = localProperties.getProperty("srcFolder");
				String basePackage = localProperties.getProperty("basePackage");
				String moduleName = localProperties.getProperty("moduleName");
				String subModuleName = localProperties.getProperty("subModuleName");
				String str10 = localProperties.getProperty("webFolder");
				if ((str1 != null) && (str1.trim().length() > 0)) {
					int i = outPanel.driverComboBox.getItemCount();
					for (int j = 0; j < i; j++) {
						DriverInfo localDriverInfo = (DriverInfo)outPanel.driverComboBox.getItemAt(j);
						if (localDriverInfo.getDbName().equalsIgnoreCase(str1)) {
							outPanel.driverComboBox.setSelectedIndex(j);
							break;
						}
					}
				}
				outPanel.driverClassTextField.setText(str2);
				outPanel.URLTextField.setText(str3);
				outPanel.userTextField.setText(str4);
				outPanel.passwordTextField.setText(str5);
				outPanel.baseFolderTextField.setText(str6);
				outPanel.projNameTextField.setText(projName);
				outPanel.srcFolderTextField.setText(str7);
				outPanel.webFolderTextField.setText(str10);
				outPanel.basePackageTextField.setText(basePackage);
				outPanel.moduleTextField.setText(moduleName);
				outPanel.subModuleTextField.setText(subModuleName);
			}
		} catch (Exception localException) {
			localException.printStackTrace();
		}
	}

	private void saveConfig() {
		try {
			String str = "app-config.properties";
			InputStream localInputStream = ClassLoader.getSystemResourceAsStream(str);
			if (localInputStream == null)
				localInputStream = getClass().getResourceAsStream(str);

			if (localInputStream != null) {
				Properties localProperties = new Properties();
				localProperties.load(localInputStream);
				localInputStream.close();
				localProperties.setProperty("driver", outPanel.driverComboBox.getSelectedItem().toString());
				localProperties.setProperty("driverClass", outPanel.driverClassTextField.getText());
				localProperties.setProperty("driverURL", outPanel.URLTextField.getText());
				localProperties.setProperty("driverUser", outPanel.userTextField.getText());
				localProperties.setProperty("driverPassword", new String(outPanel.passwordTextField.getPassword()));
				localProperties.setProperty("baseFolder", outPanel.baseFolderTextField.getText());
				localProperties.setProperty("projName", outPanel.projNameTextField.getText());
				localProperties.setProperty("srcFolder", outPanel.srcFolderTextField.getText());
				localProperties.setProperty("webFolder", outPanel.webFolderTextField.getText());
				localProperties.getProperty("basePackage", outPanel.basePackageTextField.getText());
				localProperties.setProperty("moduleName", outPanel.moduleTextField.getText());
				localProperties.setProperty("subModuleName", outPanel.subModuleTextField.getText());
			}
		} catch (Exception localException) {
			localException.printStackTrace();
		}
	}
}
